/*
  S.M.A.C.K - An operating system kernel
  Copyright (C) 2010,2011 Mattias Holm and Kristian Rietveld
  For licensing and a full list of authors of the kernel, see the files
  COPYING and AUTHORS.
*/

#ifndef KERNEL__SLABALLOC_H
#define KERNEL__SLABALLOC_H

typedef struct slab_t slab_t;

typedef struct slab_obj_t
{
  union {
    slab_t *slab;
    struct slab_obj_t *next;
  } u;
  uint32_t pad; // BUG: Not working on 64 bit targets, we need to ensure 8 byte alignment for allcoated data

  uint8_t data[];
} slab_obj_t;

struct slab_t {
  // TODO: Add slab lock
  size_t obj_size;
  slab_obj_t *first_free;
};

#define SLAB_INITIALISER(TYPE) { sizeof(TYPE), NULL}


/*!
  Creates a new slab descriptor

  \param obj_size The size of the objects allocated from this slab.
  \result A new slab descriptor
*/
slab_t slab_create(size_t obj_size);

/*! Allocate one object in a slab

  \param slab The slab from which the object is allocated
  \result NULL on failure (e.g. out of memory), otherwise a pointer to the allocated object.
 */
void* slab_alloc(slab_t *slab);

/*! Frees an object allocated with slab_alloc. Note that the space is not freed
  or released, it is reclaimed by the slab associated with the object.

  \param obj The object to free.
  \pre obj must be either NULL or allocated previously with slab_alloc
 */
void slab_free(void *obj);


#endif /* !KERNEL__SLABALLOC_H */
